﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YJKArchUtils.Utils;
using YJKRevitFamilyDataBase;

namespace YJKRevitColumn.DataDefine
{
	internal class FamilySymbolManage
	{
		public FamilySymbolManage(Autodesk.Revit.DB.Document doc)
		{
			this.m_doc = doc;
		}

		public FamilySymbol GetColumnFsByParaInfo(ColumnType eColumnType, string strWidth, string strDepth, string strMaterial)
		{
			if (!strMaterial.Contains("HY_"))
			{
				strMaterial = "HY_" + strMaterial;
			}
			string columnFamilyName = FamilySymbolManage.GetColumnFamilyName(eColumnType);
			string columnFiSName = FamilySymbolManage.GetColumnFiSName(eColumnType, strWidth, strDepth, strMaterial);
			List<FamilySymbol> list;
			if (eColumnType == ColumnType.eArchRectColumn || eColumnType == ColumnType.eArchCircleColumn)
			{
				list = this.GetColumnFiSymbolsByDoc(BuiltInCategory.OST_Columns);
			}
			else
			{
				list = this.GetColumnFiSymbolsByDoc(BuiltInCategory.OST_StructuralColumns);
			}
			list = this.GetColumnFiSymbolsByType(list, eColumnType);
			foreach (FamilySymbol familySymbol in list)
			{
				if (familySymbol.Name == columnFiSName && familySymbol.FamilyName == columnFamilyName)
				{
					return familySymbol;
				}
			}
			FamilySymbol familySymbol2 = this.CloneColumnFiSymbol(eColumnType, columnFamilyName, columnFiSName);
			if (familySymbol2 == null)
			{
				return null;
			}
			this.SetParaToFamilySymbol(familySymbol2, strWidth, strDepth, strMaterial);
			return familySymbol2;
		}

		private void SetParaToFamilySymbol(FamilySymbol familySymbol, string strWidth, string strDepth, string strMaterial)
		{
			Transaction transaction = new Transaction(this.m_doc, "LoadFamily");
			try
			{
				transaction.Start();
				Parameter parameter = familySymbol.GetParameter("材质");
				if (parameter != null)
				{
					Material materialObject = FamilySymbolManage.GetMaterialObject(this.m_doc, strMaterial);
					if (materialObject != null)
					{
						parameter.Set(materialObject.Id);
					}
				}
				parameter = FamilySymbolManage.GetFamilySymbolWidth(familySymbol);
				if (parameter != null)
				{
					double val = 0.0;
					if (double.TryParse(strWidth, out val))
					{
						parameter.Set(Common.MMToFeet(val));
					}
				}
				parameter = FamilySymbolManage.GetFamilySymbolDepth(familySymbol);
				if (parameter != null)
				{
					double val2 = 0.0;
					if (double.TryParse(strDepth, out val2))
					{
						parameter.Set(Common.MMToFeet(val2));
					}
				}
				parameter = FamilySymbolManage.GetFamilySymbolDiameter(familySymbol);
				if (parameter != null)
				{
					double val3 = 0.0;
					if (double.TryParse(strDepth, out val3))
					{
						parameter.Set(Common.MMToFeet(val3));
					}
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		public static Material GetMaterialObject(Autodesk.Revit.DB.Document doc, string strMaterialname)
		{
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Material)).ToElements())
			{
				if (element.Name.CompareTo(strMaterialname) == 0)
				{
					return element as Material;
				}
			}
			return null;
		}

		private static Parameter GetFamilySymbolWidth(FamilySymbol familySymbol)
		{
			Parameter parameter = familySymbol.GetParameter("宽度");
			if (parameter != null)
			{
				return parameter;
			}
			return familySymbol.GetParameter("Width");
		}

		private static Parameter GetFamilySymbolDepth(FamilySymbol familySymbol)
		{
			Parameter parameter = familySymbol.GetParameter("深度");
			if (parameter != null)
			{
				return parameter;
			}
			return familySymbol.GetParameter("Depth");
		}

		private static Parameter GetFamilySymbolDiameter(FamilySymbol familySymbol)
		{
			Parameter parameter = familySymbol.GetParameter("直径");
			if (parameter != null)
			{
				return parameter;
			}
			return familySymbol.GetParameter("Diameter");
		}

		private FamilySymbol CloneColumnFiSymbol(ColumnType eColumnType, string strFamilyName, string strFiSName)
		{
			FamilySymbol familySymbol = null;
			Family family = ElementFiltering.FindFamily(this.m_doc, strFamilyName);
			bool flag = false;
			if (family == null)
			{
				FamilySymbolManage.LoadColumnFamily(ref family, this.m_doc, strFamilyName);
				if (family == null)
				{
					return null;
				}
				flag = true;
			}
			familySymbol = family.GetSymbols().FirstOrDefault<FamilySymbol>();
			if (familySymbol != null)
			{
				Transaction transaction = new Transaction(this.m_doc, "RenameFamilySymbol");
				try
				{
					transaction.Start();
					if (flag)
					{
						familySymbol.Name = strFiSName;
					}
					else
					{
						familySymbol = (familySymbol.Duplicate(strFiSName) as FamilySymbol);
					}
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
			return familySymbol;
		}

		private static bool LoadColumnFamily(ref Family family, Autodesk.Revit.DB.Document doc, string strFiSName)
		{
			string text = Path.Combine(FamilyLibDatabase.GetDefFamilyLibPath(), string.Concat(new string[]
			{
				"Family\\",
				RevitVersion.Version,
				"\\Column\\",
				strFiSName,
				".rfa"
			}));
			try
			{
				Transaction transaction = new Transaction(doc, "LoadFamily");
				try
				{
					transaction.Start();
					if (!doc.LoadFamily(text, out family))
					{
						transaction.RollBack();
						return false;
					}
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
					return false;
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private static string GetColumnFiSName(ColumnType eColumnType, string strWidth, string strDepth, string strMaterial)
		{
			if (!strMaterial.Contains("HY_"))
			{
				strMaterial = "HY_" + strMaterial;
			}
			string result;
			if (eColumnType == ColumnType.eArchCircleColumn || eColumnType == ColumnType.eStruCircleColumn)
			{
				result = strMaterial + "-" + strDepth + "直径";
			}
			else
			{
				result = string.Concat(new string[]
				{
					strMaterial,
					"-",
					strWidth,
					"*",
					strDepth
				});
			}
			return result;
		}

		private static string GetColumnFamilyName(ColumnType eColumnType)
		{
			string result = "建筑柱-矩形";
			if (eColumnType == ColumnType.eArchCircleColumn)
			{
				result = "建筑柱-圆形";
			}
			else if (eColumnType == ColumnType.eStruRectColumn)
			{
				result = "结构柱-矩形";
			}
			else if (eColumnType == ColumnType.eStruCircleColumn)
			{
				result = "结构柱-圆形";
			}
			return result;
		}

		public List<FamilySymbol> GetColumnFiSymbolsByType(List<FamilySymbol> lstFamilySymbol, ColumnType eColumnType)
		{
			List<FamilySymbol> list = new List<FamilySymbol>();
			if (lstFamilySymbol == null)
			{
				return list;
			}
			int num = 0;
			int num2 = 0;
			ColumnType columnType = ColumnType.eStruOtherColumn;
			foreach (FamilySymbol familySymbol in lstFamilySymbol)
			{
				FamilySymbolManage.GetShapeTypeByFiSymbol(familySymbol, ref columnType, ref num, ref num2);
				if (columnType == eColumnType)
				{
					list.Add(familySymbol);
				}
			}
			return list;
		}

		public List<FamilySymbol> GetColumnFiSymbolsByDoc(BuiltInCategory category)
		{
			List<FamilySymbol> list = new List<FamilySymbol>();
			new List<Family>();
			foreach (Element element in new FilteredElementCollector(this.m_doc).OfClass(typeof(FamilySymbol)).OfCategory(category).ToElements())
			{
				FamilySymbol familySymbol = element as FamilySymbol;
				if (familySymbol != null)
				{
					list.Add(familySymbol);
				}
			}
			return list;
		}

		public static bool GetShapeTypeByFiSymbol(FamilySymbol familySymbol, ref ColumnType eColumnType, ref int iWidth, ref int iDepth)
		{
			iWidth = 0;
			iDepth = 0;
			eColumnType = ColumnType.eStruOtherColumn;
			bool flag = false;
			if (familySymbol.Category.Id.IntegerValue == -2000100)
			{
				flag = true;
				eColumnType = ColumnType.eArchOtherColumn;
			}
			try
			{
				foreach (object obj in familySymbol.Parameters)
				{
					Parameter parameter = (Parameter)obj;
					string name = parameter.Definition.Name;
					if (name == "宽度" || name == "Width")
					{
						if (flag)
						{
							eColumnType = ColumnType.eArchRectColumn;
						}
						else
						{
							eColumnType = ColumnType.eStruRectColumn;
						}
						double num = AssistFunc.feetToMM(parameter.AsDouble());
						iWidth = (int)num;
						if (!Geometry.LessThan(num - (double)iWidth, 0.5))
						{
							iWidth++;
						}
					}
					else if (name == "深度" || name == "Depth")
					{
						if (flag)
						{
							eColumnType = ColumnType.eArchRectColumn;
						}
						else
						{
							eColumnType = ColumnType.eStruRectColumn;
						}
						double num2 = AssistFunc.feetToMM(parameter.AsDouble());
						iDepth = (int)num2;
						if (!Geometry.LessThan(num2 - (double)iDepth, 0.5))
						{
							iDepth++;
						}
					}
					else if (name == "直径" || name == "Diameter")
					{
						if (flag)
						{
							eColumnType = ColumnType.eArchCircleColumn;
						}
						else
						{
							eColumnType = ColumnType.eStruCircleColumn;
						}
						double num3 = AssistFunc.feetToMM(parameter.AsDouble());
						iWidth = (int)num3;
						if (iWidth % 2 == 1)
						{
							iWidth++;
						}
						iDepth = iWidth / 2;
					}
					if (iWidth > 0 && iDepth > 0)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private Document m_doc;

		private ColumnType m_eColumnType;

		private string m_strWidth;

		private string m_strDepth;

		private string m_strMaterial;
	}
}
